package util

import (
	"fmt"
	"github.com/speps/go-hashids"
	"jgame-api/app"
)

type Token struct {
	hd *hashids.HashIDData
}

func NewToken(salt string, alphabet string) *Token {
	hd := hashids.NewData()
	hd.Salt = salt
	hd.Alphabet = alphabet
	hd.MinLength = 32
	return &Token{hd: hd}
}

func (t Token) Decode(token string) (int64, error) {
	if len(token) < 32 {
		return 0, fmt.Errorf("invalid token, length than 32")
	}

	// create hashids object
	h, err := hashids.NewWithData(t.hd)
	if err != nil {
		app.Logger.Errorf("create hashids failed with err: %s", err)
		return 0, err
	}

	// decode token
	uid := string([]byte(token)[:32])
	decoded, err := h.DecodeInt64WithError(uid)
	if err != nil {
		app.Logger.Errorf("decode token failed with err: %s, token: %s", err, token)
		return 0, err
	}

	if len(decoded) == 0 {
		app.Logger.Errorf("decode token failed with empty result token: %s", token)
		return 0, fmt.Errorf("decode")
	}

	return decoded[0], nil
}

func (t Token) Encode(uid int) (string, error) {
	h, err := hashids.NewWithData(t.hd)
	if err != nil {
		app.Logger.Errorf("create hashids failed with err: %s", err)
		return "", err
	}

	uidStr, err := h.Encode([]int{uid})
	if err != nil {
		app.Logger.Errorf("encode token failed with err: %d, uid: %s", err, uid)
		return "", err
	}

	return uidStr, nil
}
